package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.dto.OrderInfoDto;
import com.itheima.mapper.OrderMapper;
import com.itheima.mapper.OrderSettingMapper;
import com.itheima.pojo.Member;
import com.itheima.pojo.Order;
import com.itheima.pojo.OrderSetting;
import com.itheima.service.MemberService;
import com.itheima.service.OrderService;
import com.itheima.service.OrderSettingService;
import com.itheima.utils.DateUtil;
import com.itheima.utils.RedisUtil;
import com.itheima.utils.SnowflakeIdWorker;
import com.itheima.vo.OrderSuccessfulVo;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.util.unit.DataUnit;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author jshstart
 * @creat 2020-11-15 13:08
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Reference
    private MemberService memberService;
    @Reference
    private OrderSettingService orderSettingService;
    @Override
    public Long submitOrder(OrderInfoDto orderInfoDto) {
        //1.检验验证码是够正确
//        降级时打断点跳转火爆页面
        String rediscode = RedisUtil.get("sms:code:" + orderInfoDto.getTelephone());
        String idCard = orderInfoDto.getValidateCode();
        if (idCard==null){
            throw new RuntimeException("验证码失效或过期，请重新发送");
        }else {
            if (rediscode.equals(idCard)==false){
                throw new RuntimeException("验证码错误");
            }
        }
        //2.判断该用户是否重复预约，在一天之内预约多次即是重复预约
        //2.1首先判断该用户是否存在，
        //2.2再判断该用户在这一天是否已经有预约
        String orderDate = DateUtil.formatDate(orderInfoDto.getOrderDate());
        Member member= memberService.findMember(orderInfoDto.getTelephone());
        if (member!=null){
//            Order order= this.exist(orderDate);
            Order order= this.exist(member.getId(),orderDate);
            if (order!=null){
               throw new RuntimeException("该用户再当天已经预约，不可重复预约");
           }
        }
        //3.判断当前日期是否可以预约
       //String orderDate = DateUtil.formatDate(orderInfoDto.getOrderDate());
        OrderSetting orderSetting=orderSettingService.isFull(orderDate);
        if (orderSetting==null||orderSetting.getNumber()<=0){
            throw new RuntimeException("今天不可预约，请择日再来");
        }
        if (orderSetting.getNumber()==orderSetting.getReservations()){
            throw new RuntimeException("当天该套餐可预约用户已达上限，请择日再来，祝您生活愉快！");
        }
        return doCreateOrder(orderInfoDto,orderSetting,member);

    }

    @Override
    public Order exist(Long memberId,String orderDate) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("member_id",memberId);
        queryWrapper.eq("order_date",orderDate);
        return this.getOne(queryWrapper);
    }

    //根据流水号查询订单
    @Override
    public Order findByOrderNo(String orderNo) {

        QueryWrapper<Order> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("order_no",orderNo);
        return this.getOne(queryWrapper);
    }


    @Override
    public OrderSuccessfulVo findOrderInfo(Long id) {
      return baseMapper.findOrderInfo(id);
    }

    @Override
    public Map selectSetmealPercent() {
        Map map = new HashMap<>();
        List<Map> data = this.baseMapper.selectSetmealPercent();
        map.put("seriesData",data);
        List<String> legendData = new ArrayList<>();
        for (Map map1:data){
            legendData.add((String) map1.get("name"));
        }
        map.put("legendData",legendData);
        return map;
    }

    @Override
    public void updateByOrderNo(Map<String,String> param) {
        String tradeNo = param.get("out_trade_no");
        this.baseMapper.updateByOrderNo(tradeNo);
    }

    @Override
    public void deleteByOrderNo(String orderNo) {
        QueryWrapper<Order> queryWrapper=new QueryWrapper();
        queryWrapper.eq("order_no",orderNo);
        this.remove(queryWrapper);
    }

    @Override
    public Integer selStatus(String orderNo) {
        return this.baseMapper.selStatus(orderNo);
    }



    @Override
    public int findTodayOrderNumber(String formatDate) {
        return this.baseMapper.findTodayOrderNumber(formatDate);
    }

    @Override
    public int findTodayVisitsNumber(String formatDate) {
        return this.baseMapper.findTodayVisitsNumber(formatDate);
    }

    @Override
    public int findThisWeekOrderNumber(int thisweek) {
        return this.baseMapper.findThisWeekOrderNumber(thisweek);
    }

    @Override
    public int findThisWeekVisitsNumber(int thisweek) {
        return this.baseMapper.findThisWeekVisitsNumber(thisweek);
    }

    @Override
    public int findThisMonthOrderNumber(String thismonth) {
        return this.baseMapper.findThisMonthOrderNumber(thismonth);
    }

    @Override
    public int findThisMonthVisitsNumber(String thismonth) {
        return this.baseMapper.findThisMonthVisitsNumber(thismonth);
    }

    private Long doCreateOrder(OrderInfoDto orderInfoDto, OrderSetting orderSetting, Member member) {
        //4.成功后预约设置时的预约人数修改
        orderSetting.setReservations(orderSetting.getReservations()+1);
        orderSettingService.updateById(orderSetting);
        //5.添加或修改会员信息
        if (member==null){
            member=new Member();
            member.setCreateDate(new Date());
            member.setCreateDateId(DateUtil.formatDate(new Date(),"yyyyMMdd"));
        }
        member.setName(orderInfoDto.getName());
        member.setSex(orderInfoDto.getSex());
        member.setIdCard(orderInfoDto.getIdCard());
        member.setTelephone(orderInfoDto.getTelephone());
        memberService.saveOrUpdate(member);
        //6.生成预约订单
        Order order = new Order();
        order.setMemberId(member.getId());
        order.setOrderDate(orderInfoDto.getOrderDate());
        order.setOrderNo(String.valueOf(SnowflakeIdWorker.getInstance().nextId()));
        order.setPayStatus(0);
        order.setSetmealId(orderInfoDto.getSetmealId());
        this.save(order);
        return order.getId();
    }
}
